#include "MyFunctions.h"


#define MAXSIZE 20


#define number_length 21    //one space to put '\0'
#define class_length 21     //one space to put '\0'
#define name_length 21      //one space to put '\0'
#define sex_length 7        //one space to put '\0'
#define scores_length 5     //one space to put '\0'

typedef struct _Students
{
    char number[number_length];
    char class[class_length];
    char name[name_length];
    char sex[sex_length];
    char scores[scores_length];
}Students;
Students *ptr[MAXSIZE];
int numOfStu;        //The number of students in existence.

char *chs [10];

//============================================================

void _ShowStuInfo(int i)//Done
{
    printf("%-15s %-15s %-15s %-15s %-15s\n",
      ptr[i]->number, ptr[i]->class, ptr[i]->name, ptr[i]->sex, ptr[i]->scores);
}

void _ShowListHead()
{
    printf("Number          Class           Name            "
           "sex             scores\n");
}

//============================================================

int CheckList()         //Done
{
    if(numOfStu == 0)
    {
        printf("List is empty!!\n");
        system("pause");
        return ERROR;
    }
    else if(numOfStu < 0)
    {
        printf("numOfStu smaller than zero !!\n");
        system("pause");
    }
}

//============================================================
//00000000000000000000000000000000000000000000000000
//0000000000000000000000000000000000000000

void AddStuInfo()       //Done
{
    if(numOfStu >= MAXSIZE)
    {
        printf("List is full!!\n");
        system("pause");
        return ;
    }


    system("cls");
    ptr[numOfStu] = (Students*)malloc(sizeof(Students));

    int i;
    char chs[number_length];
    printf("Please enter the |%6s| of the student:","Number");
    MyGets(20,chs);
    for(i = 0; i < numOfStu; i++)
    {
        if(!MyStrcmp(ptr[i]->number,chs))
        {
            printf("Error!! Already has a Student Number %s !!\n",chs);
            system("pause");
            return ;
        }
    }
    MyStrcat(0,1,ptr[numOfStu]->number,chs);
    system("cls");

    printf("Please enter the |%6s| of the student:","Class");
    MyGets(20,ptr[numOfStu]->class);
    system("cls");

    printf("Please enter the |%6s| of the student:","Name");
    MyGets(20,ptr[numOfStu]->name);
    system("cls");

    printf("Please select the |%6s| of the student:\n","sex");
    printf("     Male            Female\n");

    printf("      ");
    int select = MyHorizontalSelector(16,2,1);
    if(select == 1)
        MyStrcpy(ptr[numOfStu]->sex, "Male");
    else
        MyStrcpy(ptr[numOfStu]->sex, "Female");

    system("cls");

    printf("Please enter the |%6s| of the student:","Scores");
    MyStrcat(1, MyUserInputInt(), ptr[numOfStu]->scores, "1");
    system("cls");

    numOfStu++;
}

//---------------------

void DeleteStuInfo()    //Done
{
    if(!CheckList())
        return ;

    char chs[20];
    printf("Please enter the |%6s| of the student:","Number");
    scanf("%s",chs);

    _Bool doDelete = 0;
    int i;
    for(i = 0; i < numOfStu; i++)
        if(! MyStrcmp(ptr[i]->number,chs))
        {
            _ShowListHead();
            _ShowStuInfo(i);
            printf("Press Enter to confirm, Other keys to cancel.\n");
            if(getch() != 13)
                return ;
            
            free(ptr[i]);
            ptr[i] = NULL;

            for(; i < numOfStu - 1; i++)
                ptr[i] = ptr[i + 1];

            numOfStu--;
            return ;
        }
    printf("Can't find such member!!\n");
    system("pause");
}

//---------------------

void ListStuInfo()      //Done
{
    if(!CheckList())
        return ;


    int preselection = 1;

    _ShowListHead();
    int i, k, j;
    Students *temp_ptr;
    
    _beforeEraser1:
    MyEraser(0,10,80,MAXSIZE);
    for(i = 0; i < numOfStu; i++)
        _ShowStuInfo(i);

    switch(MyHorizontalSelector(15,5,preselection))
    {
        case 1:
            preselection = 1;
            for(k = 0; k < numOfStu - 1; k++)
                for(j = 0; j < numOfStu - 1 - k; j++)
                {
                    if(MyStrIntoInt(ptr[j]->number) > MyStrIntoInt(ptr[j + 1]->number))
                    {
                        temp_ptr = ptr[j];
                        ptr[j] = ptr[j + 1];
                        ptr[j + 1] = temp_ptr;
                    }
                }
            goto _beforeEraser1;
        case 2:
            preselection = 2;
            for(k = 0; k < numOfStu - 1; k++)
                for(j = 0; j < numOfStu - 1 - k; j++)
                {
                    if(MyStrcmp(ptr[j]->class, ptr[j + 1]->class) == -1)
                    {
                        temp_ptr = ptr[j];
                        ptr[j] = ptr[j + 1];
                        ptr[j + 1] = temp_ptr;
                    }
                }
            goto _beforeEraser1;
        case 3:
            preselection = 3;
            for(k = 0; k < numOfStu - 1; k++)
                for(j = 0; j < numOfStu - 1 - k; j++)
                {
                    if(MyStrcmp(ptr[j]->name, ptr[j + 1]->name) == -1)
                    {
                        temp_ptr = ptr[j];
                        ptr[j] = ptr[j + 1];
                        ptr[j + 1] = temp_ptr;
                    }
                }
            
            goto _beforeEraser1;
        case 4:
            preselection = 4;
            for(k = 0; k < numOfStu - 1; k++)
                for(j = 0; j < numOfStu - 1 - k; j++)
                {
                    if(MyStrcmp(ptr[j]->sex, ptr[j + 1]->sex) == 1)
                    {
                        temp_ptr = ptr[j];
                        ptr[j] = ptr[j + 1];
                        ptr[j + 1] = temp_ptr;
                    }
                }
            goto _beforeEraser1;
        case 5:
            preselection = 5;
            for(k = 0; k < numOfStu - 1; k++)
                for(j = 0; j < numOfStu - 1 - k; j++)
                {
                    if(MyStrIntoInt(ptr[j]->scores) > MyStrIntoInt(ptr[j + 1]->scores))
                    {
                        temp_ptr = ptr[j];
                        ptr[j] = ptr[j + 1];
                        ptr[j + 1] = temp_ptr;
                    }
                }
            
            goto _beforeEraser1;
        default:
            return ;
    }
    system("pause");
}

//---------------------

void ShowStuInfo()      //Done
{
    if(!CheckList())
        return ;
    
    char chs[20];
    printf("Please enter the |%6s| of the student:","Number");
    scanf("%s",chs);

    int i;
    for(i = 0; i < numOfStu; i++)
        if(! MyStrcmp(ptr[i]->number,chs))
        {
            _ShowListHead();
            _ShowStuInfo(i);
            system("pause");
            return ;
        }

    printf("Can't find such member!!\n");
    system("pause");
}

//---------------------

void FindInfo()         //Done
{
    if(!CheckList())
        return ;

    _Bool isFound = 0;
    char chs[name_length];      //this name_length without meaning.
    printf("Please enter the information you want to find:");
    MyGets(name_length ,chs);

    int i;
    for(i = 0; i < numOfStu; i++)
    {
        if((!Myabs(MyStrcmp(ptr[i]->number,chs)))
          ||(!Myabs(MyStrcmp(ptr[i]->name,chs)))
          ||(!Myabs(MyStrcmp(ptr[i]->class,chs)))
          ||(!Myabs(MyStrcmp(ptr[i]->sex,chs)))
          ||(!Myabs(MyStrcmp(ptr[i]->scores,chs))))
          {
              if(i == 0)
                  _ShowListHead();
              _ShowStuInfo(i);
              isFound = 1;
              continue;
          }
    }
    
    if(isFound == 0)
        printf("There's no such info in the List.\n");
    
    system("pause");
}

//---------------------

void ModifyInfo()       //Done
{
    if(!CheckList())
        return ;

    char chs[20];
    printf("Please enter the |%6s| of the student:","Number");
    MyGets(20,chs);

    int i;
    for(i = 0; i < numOfStu; i++)
        if(! MyStrcmp(ptr[i]->number,chs))
        {
            int preselection = 1;
            _beforeEraser:
            MyEraser(0,8,80,15);
            _ShowListHead();
            _ShowStuInfo(i);
            switch(MyHorizontalSelector(15,5,preselection))
            {
                case 1:
                    preselection = 1;
                    int k;
                    char chs[number_length];
                    printf("Please enter the |%6s| of the student:","Number");
                    MyGets(20,chs);
                    for(k = 0; k < numOfStu; k++)
                    {
                        if(!MyStrcmp(ptr[k]->number,chs))
                        {
                            printf("Error!! Already has a Student Number %s !!\n",chs);
                            system("pause");
                            goto _beforeEraser;
                        }
                    }
                    MyStrcat(0,1,ptr[i]->number,chs);
                    goto _beforeEraser;
                case 2:
                    preselection = 2;
                    printf("Please enter the |%6s| of the student:","Class");
                    MyGets(20,ptr[i]->class);
                    goto _beforeEraser;
                case 3:
                    preselection = 3;
                    printf("Please enter the |%6s| of the student:","Name");
                    MyGets(20,ptr[i]->name);
                    goto _beforeEraser;
                case 4:
                    preselection = 4;
                    printf("Please select the |%6s| of the student:\n","sex");
                    printf("     Male            Female\n");

                    printf("      ");
                    int select = MyHorizontalSelector(16,2,1);
                    if(select == 1)
                        MyStrcpy(ptr[i]->sex, "Male");
                    else
                        MyStrcpy(ptr[i]->sex, "Female");

                    goto _beforeEraser;
                case 5:
                    preselection = 5;
                    printf("Please enter the |%6s| of the student:","Scores");
                    MyStrcat(1, MyUserInputInt(), ptr[i]->scores, "1");
                    goto _beforeEraser;
                default:
                    return ;
            }
        }
    
    printf("Can't find such member!!\n");
    system("pause");
}

//---------------------

void Debug()
{
    srand((unsigned)time(NULL));
    static _Bool Done = 0;
    if(Done == 1)
    {
        printf("This selection only can be used once!!\n");
        system("pause");
        return ;
    }


    int i, k;
    char chs[20];
    char *chs_p = chs;
    for(i = 0; i < MAXSIZE; i++)
    {
        ptr[i] = (Students*)malloc(sizeof(Students));
        MyStrcat(1,i + 1,ptr[i]->number,"1");

        MyStrcat(0,1,chs,"200");
        MyStrcat(1,rand() % 5 + 1,chs,"0");
        MyStrcat(0,1,ptr[i]->class,chs);

        for(k = 0; k < rand() % 6 + 4; k++)
        {
            *(chs_p + k) = rand() % 26 + 97;
        }
        *(chs_p + k) = '\0';
        MyStrcat(0,1,ptr[i]->name,chs);

        if(rand() % 2)
            MyStrcat(0,1,ptr[i]->sex,"Male");
        else
            MyStrcat(0,1,ptr[i]->sex,"Female");

        MyStrcat(1,rand() % 101,ptr[i]->scores,"1");
    }

    numOfStu = MAXSIZE;
    Done = 1;

    printf("Create random List successful!!\n");
    system("pause");

}

//---------------------

void ListToFile()
{
    FILE *fp;
    fp = fopen("Student_List.txt","w");

    fprintf(fp, "%d\n", numOfStu);
    int i;
    for(i = 0; i < numOfStu; i++)
    {
        fprintf(fp, "%-15s %-15s %-15s %-15s %-15s\n",
          ptr[i]->number, ptr[i]->class, ptr[i]->name, ptr[i]->sex, ptr[i]->scores);
    }

    fclose(fp);
}

void FileToList()
{
    FILE *fp;
    fp = fopen("Student_List.txt","r");

    fscanf(fp, "%d", &numOfStu);
    int i;
    for(i = 0; i < numOfStu; i++)
    {
        ptr[i] = (Students*)malloc(sizeof(Students));
        fscanf(fp, "%s %s %s %s %s",
          ptr[i]->number, ptr[i]->class, ptr[i]->name, ptr[i]->sex, ptr[i]->scores);
    }

    fclose(fp);
}

//0000000000000000000000000000000000000000
//00000000000000000000000000000000000000000000000000
//============================================================

void Initialize()   //Done
{
    MyShowOrHideCursor(0);
    MySetConsoleSize(85,40);
    FileToList();

    int i;
    for(i = 0; i < 10; i++)
        chs[i] = (char*)malloc(20);
    
    chs[0] = "1.Add student";
    chs[1] = "2.Delete student";
    chs[2] = "3.Modify information";
    chs[3] = "4.Find information";
    chs[4] = "5.List all student";
    chs[5] = "6.Show student info";
    chs[6] = "";
    chs[7] = "";
    chs[8] = "9.Debug:Random List";
    chs[9] = "0.Exit";
}

//============================================================

void Menu(int select)//Done
/**
 * if select is negetive,function will print all string
 * else select a string to print
 */
{
    int i = 0;

    if(select == 0)
        select = 10;

    system("cls");
    printf("\n\n");

    if(select < 0)
    {
        printf("____________________________________\n");

        for(i = 0; i < 10; i++)
        {
            printf("|       %-20s       |\n",chs[i]);
        }

        printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
        printf("    Press the number to operate");
    }
    else if(select < 1 || select > 10)
            printf("menu error\n");
    else
    {
        for(i = 0; i <= select; i++)
            if(i == select)
                printf("        %-20s   <------Press again to confirm.\n%-38sOther key to cancel\n",chs[i - 1],"");
            else
                printf("\n");
    }
}

//============================================================

void Operate(int select)
{
    switch(select)
    {
        case 1:
            AddStuInfo();
            break;
        case 2:
            DeleteStuInfo();
            break;
        case 3:
            ModifyInfo();
            break;
        case 4:
            FindInfo();
            break;
        case 5:
            ListStuInfo();
            break;
        case 6:
            ShowStuInfo();
            break;
        case 9:
            Debug();
            break;
        case 0:
            ListToFile();
            exit(0);
            break;

        default:
            printf("switch in Operate Rrror!!!\n");
            Sleep(500);
            
    }
}

//============================================================

int main()
{
    MyLoginSystem();

    Initialize();
    
    while(1)
    {
        int select;
        Menu(-1);
        select = getch() - 48;
        Menu(select);
        if(select == getch() - 48)
            Operate(select);
    }

    return 0;
}

/*

*/